package com.Main;

import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.rmi.ConnectException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;


import com.protocols.BCDNumber;
import com.protocols.BinaryInteger;
import com.protocols.OctaveInteger;
import com.protocols.ProtoOperations;
import com.protocols.ProtocolStackException;
import com.protocols.sctp.m3ua.*;
import com.protocols.sctp.m3ua.sccp.CallPartyAddress;
import com.protocols.sctp.m3ua.sccp.SccpUnitDataMsg;
import com.protocols.sctp.m3ua.sccp.tcap.*;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelActvityTest;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelApplyCharging;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelApplyChargingReport;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelConnect;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelContinue;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelEventReportBCSM;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelHandlerInterface;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelInitialDP;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelReject;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelReleaseCall;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelRequestReportBCSMEvent;
import com.protocols.sctp.m3ua.sccp.tcap.camel.CamelReturnResultLast;
public class test {

	/**
	 * @param args
	 */
	public static void main(String[] args)throws Exception {
		/*
	
		// M3UA
		M3uaPayLoadData pay = new M3uaPayLoadData(3);// SCCP		
		pay.NetworkAppearance.setNetworkAppearance(2);
		pay.RoutingContext.setRoutingContext(10);
		pay.ProtocolData.setOPC(2041);
		pay.ProtocolData.setDPC(1986);
		pay.ProtocolData.setNI(2);
		pay.ProtocolData.setMP(0);
		pay.ProtocolData.setSLS(1);
		pay.CorrelationID.setCorrelationId(322);
		
		// SCCP
		
		SccpUnitDataMsg sccp = new SccpUnitDataMsg();
		sccp.CalledParty.setRoutingIndicator(0);
		sccp.CalledParty.setGTIndicator(4);
		sccp.CalledParty.setPointCode(2031);
		sccp.CalledParty.setSubSystemNumber(146);
		sccp.CalledParty.setGTTranslationType(0);
		sccp.CalledParty.setGTNumPlan(1);
		sccp.CalledParty.setGTNatureOfAddress(4);
		sccp.CalledParty.setGlobalTitle("9472000026");
		sccp.CallingParty.setRoutingIndicator(0);
		sccp.CallingParty.setGTIndicator(4);
		sccp.CallingParty.setPointCode(2040);
		sccp.CallingParty.setGTTranslationType(0);
		sccp.CallingParty.setGTNumPlan(1);
		sccp.CallingParty.setGTNatureOfAddress(4);
		sccp.CallingParty.setGlobalTitle("9472000041");
		
		
		//TCAP Begin
		TcapBegin begin = new TcapBegin();		
		begin.setApplicationContext(0x04000001003201L);
		begin.setSourceTransactionID(328873);

		//TCAP Continue
		TcapContinue cont = new TcapContinue();
		cont.setApplicationContext(0x04000001003201L);
		cont.setSourceTransactionID(328873);
		cont.setDestinationTransactionID(328);
		cont.setResult(0);
		cont.setDialogServiceUser(0);
		
		//TCAP End
		TcapEnd  tcapend = new TcapEnd();
		tcapend.setDestinationTransactionID(3874);
		
		
		
		// CAMEL Initial DP
		CamelInitialDP idp = new CamelInitialDP();		
		idp.setInvokeID(1);		
		idp.setCalledNumber(0x8413, "94729224902");
		idp.setCallingPartyCategory(10);
		//idp.setLocationNumber(84171403438703L);
		idp.setBearerCap(0x8090a3);
		idp.setEvetTypeBCSM(2);
		//idp.setIMSI("413030202545859");
		//idp.setAgeofLocationInfo(0);
		//idp.setVLRNumber(0x91, "9472000041");
		//idp.setCellID( 0x14f33004a312afL);
		idp.setExtBasicServiceCode(17);
		idp.setCallRefNumber(0x070f36b1);
		idp.setMSCNumber(0x91, "9472000041");
		idp.setCalledNumber(0x81, "0772713725");
		idp.setTimeInfo("2010090621150722");
		
		// CAMEL Request Report BCSM
		CamelRequestReportBCSMEvent requestreport = new CamelRequestReportBCSMEvent();
		requestreport.setInvokeID(81);
		requestreport.BCSMEvent1.setBCSMEvent(2, 0);
		requestreport.BCSMEvent1.setLegId(true, 1);
		
		//Activity Test
		CamelActvityTest activitest = new CamelActvityTest();
		activitest.setInvokeID(81);
		
		//Apply Charging
		CamelApplyCharging applycharging = new CamelApplyCharging();
		applycharging.setInvokeID(86);
		applycharging.SendingSideID(1);
		applycharging.setMaxCallPeriod(354);
		applycharging.setReleaseIfDurationExceed(false);
		
		// Apply Charging Report
		CamelApplyChargingReport applychargingreport = new CamelApplyChargingReport();
		applychargingreport.setInvokeID(81);
		applychargingreport.setPartyToCharge(1);
		applychargingreport.setLegActive(true);
		//applychargingreport.setTimeIfNoTariffSwitch(4545);
		applychargingreport.setTimeSinceTariffSwitch(56);
		applychargingreport.setTariffSwitchInterval(78);
		
		
		//Event Report BCSM
		CamelEventReportBCSM eventreportbcsm = new CamelEventReportBCSM();
		//eventreportbcsm.setEventTypeBCSM(10);
		eventreportbcsm.setMissCallInfo(1);
		eventreportbcsm.setInvokeID(87);
		eventreportbcsm.setLegId(1);
		eventreportbcsm.setEventSpecificInformationBCSM(5, 2, 0, 17);
		
		
		// Release Call
		CamelReleaseCall release = new CamelReleaseCall();
		release.setCause(0, 0, 31);
		release.setInvokeID(86);
		
		//Camel Continue
		CamelContinue camelcontinue = new CamelContinue();
		camelcontinue.setInvokeID(86);
		
		// Camel 
		CamelConnect camelconnect = new CamelConnect();
		camelconnect.setInvokeID(86);
		camelconnect.setDestinationNumber(0x8310, "89766");
		
		//camel reject
		
		CamelReject reject = new CamelReject();
		reject.setGeneralProblem(1);
		reject.setInvokeID(89);
		reject.setInvokeProblem(2);
		reject.setReturnErrorProblem(2);
		reject.setReturnResultProblem(3);
		

		//Camel Return Result
		
		CamelReturnResultLast returnresult = new CamelReturnResultLast();
		returnresult.setInvokeID(87);
		
		pay.ProtocolData.Payload=sccp;
		sccp.Payload=begin;
		//begin.ComponentPortion.addElement(idp.getRootComponent());
		begin.ComponentPortion.addElement(idp.getRootComponent());
		ProtoOperations.getWireSharkPcap(pay.getByteArray());
		
		//M3uaPayLoadData nnnn = new M3uaPayLoadData(3);
		//nnnn.decode(pay.getByteArray());
		
		//ProtoOperations.getWireSharkPcap(pay.getByteArray());
		
		*/
		TcapPrimitiveUnitString test = new TcapPrimitiveUnitString(0x4);
		test.setTagValue("It's havin Mal-chractor at the end.");
		//System.out.println(ProtoOperations.getHexString(test.getByteArray()));
		
		String abc="123456";
		byte[] byteabc=encode7bit(abc.getBytes());
		String strngabc=new String( decode7bit(byteabc));
		System.out.println(ProtoOperations.getHexString(encode7bit(abc.getBytes())));
		System.out.println(strngabc);
		}
	
	
	public static byte[] decode7bit(byte[] input) {
		int fillBits=0;
		final int[] upperBits = {
		0xFE, // 0 = B7|B6|B5|B4|B3|B2|B1
		0xFC, // 1 = B7|B6|B5|B4|B3|B2
		0xF8, // 2 = B7|B6|B5|B4|B3
		0xF0, // 3 = B7|B6|B5|B4
		0xE0, // 4 = B7|B6|B5
		0xC0, // 5 = B7|B6
		0x80  // 6 = B7
		};    
		
		final int[] lowerBits = {
		0x01, // 0 =                   B0
		0x03, // 1 =                B1|B0
		0x07, // 2 =             B2|B1|B0
		0x0F, // 3 =          B3|B2|B1|B0
		0x1F, // 4 =       B4|B3|B2|B1|B0
		0x3F, // 5 =    B5|B4|B3|B2|B1|B0
		0x7F  // 6 = B6|B5|B4|B3|B2|B1|B0
		};    
		
		final int length = input.length;
		if (fillBits != 0) {
		final int len = length - 1;
		final int cut = lowerBits[fillBits - 1];
		final int move = 8 - fillBits;
		
			for (int f = 0; f < len; f++) {
			input[f] >>= fillBits;
			input[f] = (byte)((input[f + 1] & cut) << move);
			}
		input[len] >>= fillBits;
		}    
		
		int inputlength = length * 8 / 7;
		final byte[] output = new byte[inputlength];    
		
		int b = 6, p = 0;
		for (int i = 0; i < inputlength; i++) {
		switch (b) {
		case 7: // U0
		output[i] = (byte)((input[p] & upperBits[0]) >> 1);  
		break;        
		
		case 6: // L6
		output[i] = (byte)(input[p] & lowerBits[b]);
		break;
		
		default: // The rest
		output[i] =(byte)( ((input[p] & lowerBits[b]) << (6 - b))	+ ((input[p-1] & upperBits[b+1]) >> (b+2)));
		break;
		}
		
		if (--b == -1) b = 7;
		else p++;
		}
		
		return output;
	}
	
	
	public static byte[] encode7bit(byte[] input) {
		int fillBits=0;
	    final byte[] upperBits = {
	        (byte)0xFE, // 0 = B7|B6|B5|B4|B3|B2|B1
	        (byte)0xFC, // 1 = B7|B6|B5|B4|B3|B2
	        (byte)0xF8, // 2 = B7|B6|B5|B4|B3
	        (byte)0xF0, // 3 = B7|B6|B5|B4
	        (byte)0xE0, // 4 = B7|B6|B5
	        (byte)0xC0, // 5 = B7|B6
	        (byte)0x80  // 6 = B7
	    };
	    
	    final int[] lowerBits = {
	        0x01, // 0 =                   B0
	        0x03, // 1 =                B1|B0
	        0x07, // 2 =             B2|B1|B0
	        0x0F, // 3 =          B3|B2|B1|B0
	        0x1F, // 4 =       B4|B3|B2|B1|B0
	        0x3F, // 5 =    B5|B4|B3|B2|B1|B0
	        0x7F  // 6 = B6|B5|B4|B3|B2|B1|B0
	    };

	    final int inputlength = input.length;
	    final int ol = (inputlength * 7) / 8;
	    final boolean rest = ol != (double)inputlength * 7 / 8;
	    final boolean fill = fillBits != 0;
	    byte[] output = new byte[ol + (fill ? 1 : 0) + (rest ? 1 : 0)];

	    int b = 0, p = 0;
	    for (int i = 0; i < ol; i++) {
	      output[i] = (byte)((input[p] >> b)+ ((input[p + 1] & lowerBits[b]) << 7 - b));
	      if (++b == 7) {
	        b = 0;
	        p++;
	      }
	      p++;
	    }
	    if (rest) 
	    	output[ol] =(byte)( input[p] >> b);   

	    if (fill) {
	      final int cut = upperBits[7 - fillBits];
	      final int move = 8 - fillBits;
	      p = 0;
	      for (int i = 0; i <= ol + 1; i++) {
	        b = output[i] & cut;
	        output[i] ^= b;
	        output[i] <<= fillBits;
	        if (p != 0) output[i] = (byte)p;
	        p = b >> move;
	      }
	    }

	    return output;
	  }


}
